package bueu.bexl;

import java.util.LinkedHashMap;
import java.util.Map;

public class Bexl {

	private final static LinkedHashMap<String, BexlExpr> CACHE
		= new LinkedHashMap<String, BexlExpr>() {

			private static final long serialVersionUID = -7243310034139080507L;
			private static final int MAX_ENTRIES = 100;
	
			protected boolean removeEldestEntry(Map.Entry<String, BexlExpr> eldest) {
				return size() > MAX_ENTRIES;
			}
		};
		
	protected final static BexlCtx DEFAULT_CTX = new BexlCtx();

	public final static BexlExpr compile(String expr) {
		BexlExpr compiled = CACHE.get(expr);
		
		if (compiled == null) {
			compiled = Parser.parse(expr);
			CACHE.put(expr, compiled);
		}
		
		return compiled;
	}

	public final static Object get(Object root, String expr) throws BexlException {
		return compile(expr).get(DEFAULT_CTX, root);
	}
	
	public final static Object get(String expr) throws BexlException {
		return compile(expr).get(DEFAULT_CTX, null);
	}
	
	public final static Object[] list(String expr) throws BexlException {
		return compile(expr).list(DEFAULT_CTX, null);
	}

	public final static Object[] list(Object root, String expr) throws BexlException {
		return compile(expr).list(DEFAULT_CTX, root);
	}

	public final static void set(Object root, String expr, Object value) {
		BexlExpr compiled = compile(expr);
		
		if (compiled instanceof ReferenceExpr) {
			((ReferenceExpr) compiled).setValue(DEFAULT_CTX, root, value);
			return;
		}

		throw new BexlException("La expresion no es settable "+ compiled.getClass()); 
	}
	
	public final static void setForAll(String rootExpr, String getExpr, Object value) {
		DEFAULT_CTX.setForAll(rootExpr, getExpr, value);
	}
}
